using System;
using NUnit.Framework;

namespace ComponentTracer.Tests
{
    [TestFixture]
    public class ComponentTracerTests
    {
        [Test]
        public void Methoden_Aufruf_ohne_Parameter_wird_getraced() {
            var traceOutput = "";
            var service = new Service {
                CallMeAction = () => traceOutput += "I was called\n"
            };

            var tracedService = TracerProxy.Create<IService>(service, s => { traceOutput += s; });
            tracedService.CallMe_0();

            Assert.That(traceOutput, Is.EqualTo("ComponentTracer.Tests.Service.CallMe_0([])\nI was called\n"));
        }

        [Test]
        public void Methoden_Aufruf_mit_einem_Parameter_wird_getraced() {
            var traceOutput = "";
            var service = new Service {
                CallMeAction = () => traceOutput += "I was called\n"
            };

            var tracedService = TracerProxy.Create<IService>(service, s => { traceOutput += s; });
            tracedService.CallMe_1("hi");

            Assert.That(traceOutput, Is.EqualTo("ComponentTracer.Tests.Service.CallMe_1([\"hi\"])\nI was called\n"));
        }

        [Test]
        public void Methoden_Aufruf_mit_mehreren_Parameter_wird_getraced() {
            var traceOutput = "";
            var service = new Service {
                CallMeAction = () => traceOutput += "I was called\n"
            };

            var tracedService = TracerProxy.Create<IService>(service, s => { traceOutput += s; });
            tracedService.CallMe_4(42, 2.70, "hi", 56);

            Assert.That(traceOutput, Is.EqualTo("ComponentTracer.Tests.Service.CallMe_4([42,2.7,\"hi\",56])\nI was called\n"));
        }

        [Test]
        public void Funktions_Aufruf_mit_mehreren_Parameter_wird_getraced() {
            var traceOutput = "";
            var service = new Service {
                CallMeAction = () => traceOutput += "I was called\n"
            };

            var tracedService = TracerProxy.Create<IService>(service, s => { traceOutput += s; });
            tracedService.Func_3(42, "a", true);

            Assert.That(traceOutput, Is.EqualTo("ComponentTracer.Tests.Service.Func_3([42,\"a\",true])\nI was called\nreturns [\"Pat\"]\n"));
        }
    }

    public interface IService
    {
        void CallMe_0();

        void CallMe_1(string parameter);

        void CallMe_4(int parameter1, double parameter2, string parameter3, object parameter4);

        string Func_3(int parameter1, string parameter2, bool parameter3);
    }

    public class Service : IService
    {
        public Action CallMeAction = () => {};

        public void CallMe_0() {
            CallMeAction();
        }

        public void CallMe_1(string parameter) {
            CallMeAction();
        }

        public void CallMe_4(int parameter1, double parameter2, string parameter3, object parameter4) {
            CallMeAction();
        }

        public string Func_3(int parameter1, string parameter2, bool parameter3) {
            CallMeAction();
            return "Pat";
        }
    }
}